package com.xbongbong.paas.mirror.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.admin.pojo.dto.MirrorChartPreviewDTO;
import com.xbongbong.admin.pojo.dto.MirrorInstallAllDTO;
import com.xbongbong.admin.pojo.dto.MirrorInstallDTO;
import com.xbongbong.admin.pojo.dto.MirrorInstructionAllDTO;
import com.xbongbong.admin.pojo.dto.MirrorInstructionDTO;
import com.xbongbong.admin.pojo.dto.MirrorMenuListAllDTO;
import com.xbongbong.admin.pojo.dto.MirrorMenuListDTO;
import com.xbongbong.admin.pojo.dto.MirrorPreviewDTO;
import com.xbongbong.admin.pojo.dto.MirrorRollBackDTO;
import com.xbongbong.admin.pojo.vo.MirrorChartListAllVO;
import com.xbongbong.admin.pojo.vo.MirrorChartListVO;
import com.xbongbong.admin.pojo.vo.MirrorChartPreviewVO;
import com.xbongbong.admin.pojo.vo.MirrorConfigListVo;
import com.xbongbong.admin.pojo.vo.MirrorConfigVO;
import com.xbongbong.admin.pojo.vo.MirrorInstallAllVO;
import com.xbongbong.admin.pojo.vo.MirrorInstallVO;
import com.xbongbong.admin.pojo.vo.MirrorInstructionAllVO;
import com.xbongbong.admin.pojo.vo.MirrorInstructionVO;
import com.xbongbong.admin.pojo.vo.MirrorMenuListVO;
import com.xbongbong.admin.pojo.vo.MirrorPreviewVO;
import com.xbongbong.admin.pojo.vo.MirrorRollBackVO;
import com.xbongbong.admin.pojo.vo.MirrorSystemMenuListVO;
import com.xbongbong.admin.pojo.vo.MirrorUpdateVO;
import com.xbongbong.admin.pojo.vo.MirrorWorkOrderListVO;
import com.xbongbong.admin.service.MirrorService;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.MirrorErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.script.pojo.dto.MirrorUpdateDTO;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * @author xingxing.xiao
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/mirror")
public class MirrorController {
    @Resource
    private MirrorService mirrorService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    /**
     * 镜像安装
     * @param mirrorInstallDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/install", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String install(@RequestBody MirrorInstallDTO mirrorInstallDTO, BindingResult br) {
        XbbResponse<MirrorInstallVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorInstallVO mirrorInstallVO = mirrorService.install(mirrorInstallDTO);
                response = new XbbResponse<>(mirrorInstallVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 镜像组合同时安装应用和图表
     * @param mirrorInstallAllDTO
     * @param br
     * @author youli.chen
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/installAll", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String installAll(@RequestBody MirrorInstallAllDTO mirrorInstallAllDTO, BindingResult br) {
        XbbResponse<MirrorInstallAllVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorInstallAllVO mirrorInstallAllVO = mirrorService.installAll(mirrorInstallAllDTO);
                response = new XbbResponse<>(mirrorInstallAllVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 镜像菜单
     * @param mirrorMenuListDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/getMenuList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMenuList(@RequestBody MirrorMenuListDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorMenuListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorMenuListVO mirrorMenuListVO = mirrorService.getMenuList(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorMenuListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 组合镜像菜单
     * @param mirrorMenuListDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/getMenuListAll", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMenuList(@RequestBody MirrorMenuListAllDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorMenuListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorMenuListVO mirrorMenuListVO = mirrorService.getMenuListAll(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorMenuListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 工单镜像列表
     * @param mirrorMenuListDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/workorder/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWorkOrderList(@RequestBody MirrorMenuListDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorWorkOrderListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorWorkOrderListVO mirrorWorkOrderListVO = mirrorService.getWorkOrderList(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorWorkOrderListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 工单镜像列表
     * @param mirrorMenuListDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/workorder/list/all", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWorkOrderListAll(@RequestBody MirrorMenuListAllDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorWorkOrderListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorWorkOrderListVO mirrorWorkOrderListVO = mirrorService.getWorkOrderListAll(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorWorkOrderListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 表单镜像列表
     * @param mirrorMenuListDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/system/form/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getSystemFormList(@RequestBody MirrorMenuListDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorSystemMenuListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorSystemMenuListVO mirrorSystemMenuListVO = mirrorService.getSystemFormList(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorSystemMenuListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 组合表单镜像列表
     * @param mirrorMenuListAllDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/system/form/list/all", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getSystemFormList(@RequestBody MirrorMenuListAllDTO mirrorMenuListAllDTO, BindingResult br) {
        XbbResponse<MirrorSystemMenuListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorSystemMenuListVO mirrorSystemMenuListVO = mirrorService.getSystemFormListAll(mirrorMenuListAllDTO);
                response = new XbbResponse<>(mirrorSystemMenuListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 图表镜像列表
     * @param mirrorMenuListDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/chart/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChartList(@RequestBody MirrorMenuListDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorChartListVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorChartListVO mirrorChartListVO = mirrorService.getChartList(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorChartListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 图表镜像列表
     * @param mirrorMenuListDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/chart/list/all", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChartListAll(@RequestBody MirrorMenuListAllDTO mirrorMenuListDTO, BindingResult br) {
        XbbResponse<MirrorChartListAllVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorChartListAllVO mirrorChartListVO = mirrorService.getChartListAll(mirrorMenuListDTO);
                response = new XbbResponse<>(mirrorChartListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 镜像图表预览
     * @param mirrorChartPreviewDTO
     * @return
     * @throws XbbException
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/chart/preview", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChartPreview(@RequestBody MirrorChartPreviewDTO mirrorChartPreviewDTO, BindingResult br) {
        XbbResponse<MirrorChartPreviewVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorChartPreviewVO mirrorChartPreviewVO = mirrorService.getChartPreview(mirrorChartPreviewDTO);
                response = new XbbResponse<>(mirrorChartPreviewVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 镜像表单预览
     * @param mirrorPreviewDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/preview", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String preview(@RequestBody MirrorPreviewDTO mirrorPreviewDTO, BindingResult br) {
        XbbResponse<MirrorPreviewVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorPreviewVO mirrorPreviewVO = mirrorService.preview(mirrorPreviewDTO);
                response = new XbbResponse<>(mirrorPreviewVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 镜像配置信息
     * @param mirrorInstructionDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/getMirrorInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMirrorInfo(@RequestBody MirrorInstructionDTO mirrorInstructionDTO, BindingResult br) {
        XbbResponse<MirrorConfigVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorConfigVO mirrorConfigVO = mirrorService.getMirrorInfo(mirrorInstructionDTO);
                response = new XbbResponse<>(mirrorConfigVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 镜像简介
     * @param mirrorInstructionDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/getMirrorInstruction", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMirrorInstruction(@RequestBody MirrorInstructionDTO mirrorInstructionDTO, BindingResult br) {
        XbbResponse<MirrorInstructionVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorInstructionVO mirrorInstructionVO = mirrorService.getMirrorInstruction(mirrorInstructionDTO);
                response = new XbbResponse<>(mirrorInstructionVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 组合镜像简介
     * @param mirrorInstructionAllDTO
     * @param br
     * @author youli.chen
     * @date 2019/1/18 17:15
     */
    @RequestMapping(value = "/getMirrorInstructionAll", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMirrorInstructionAll(@RequestBody MirrorInstructionAllDTO mirrorInstructionAllDTO, BindingResult br) {
        XbbResponse<MirrorInstructionAllVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorInstructionAllVO mirrorInstructionAllVO = mirrorService.getMirrorInstructionAll(mirrorInstructionAllDTO);
                response = new XbbResponse<>(mirrorInstructionAllVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 更新镜像配置表中图标简介信息(脚本调用)
     * @author xingxing.xiao
     */
    @RequestMapping(value = "/updateMirrorInfoScript", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String updateMirrorInfoScript(@RequestBody MirrorUpdateDTO mirrorUpdateDTO, BindingResult br) throws Exception {
        XbbResponse<MirrorUpdateVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorUpdateVO mirrorUpdateVO = mirrorService.updateMirrorInfoScript(mirrorUpdateDTO);
                response = new XbbResponse<>(mirrorUpdateVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 回退到镜像安装之前的一个版本
     * @param mirrorRollBackDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/rollBackToPrevious", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String rollBackToPrevious(@RequestBody MirrorRollBackDTO mirrorRollBackDTO, BindingResult br) {
        XbbResponse<MirrorRollBackVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // 校验该公司一天之内对该应用的回退操作次数(最多两次)
                String hashKey = mirrorRollBackDTO.getTargetCorpid() + "_" + mirrorRollBackDTO.getAlias();
                String value = paasRedisHelper.getValue(RedisPrefixConstant.MIRROR_ROLLBACK, hashKey);
                if (Objects.nonNull(value)){
                    if (Objects.equals(Integer.valueOf(value),0)){
                        response = new XbbResponse<>(new XbbException(MirrorErrorCodeEnum.API_ERROR_403007));
                        return JSON.toJSONString(response);
                    }
                }
                MirrorRollBackVO mirrorRollBackVO = mirrorService.rollBackToPrevious(mirrorRollBackDTO);
                response = new XbbResponse<>(mirrorRollBackVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/checkData", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String checkData(@RequestBody MirrorRollBackDTO mirrorRollBackDTO, BindingResult br) {
        XbbResponse<MirrorRollBackVO> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorRollBackVO mirrorRollBackVO = mirrorService.checkData(mirrorRollBackDTO);
                response = new XbbResponse<>(mirrorRollBackVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/getMirrorConfigList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMirrorConfigList(@RequestBody BaseDTO baseDTO, BindingResult br) {
        XbbResponse<MirrorConfigListVo> response;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MirrorConfigListVo mirrorConfigListVo = mirrorService.getMirrorConfigList();
                response = new XbbResponse<>(mirrorConfigListVo);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
}
